package com.sky.server;

import com.sky.constant.NettyConstant;
import com.sky.constant.RedisConstant;
import com.sky.entity.MessageRequest;
import com.sky.util.NettyUtils;
import com.sky.utils.RedisHashUtils;
import com.sky.utils.StringUtils;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.redisson.codec.SerializationCodec;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class RedisReceiver implements ApplicationRunner, Ordered {

    @Resource
    private RedissonClient redissonClient ;

    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    public void run(ApplicationArguments args) {
        try {
            RTopic topic = redissonClient.getTopic(RedisConstant.REDISSON_TOPIC,new SerializationCodec());
            topic.addListener(String.class, (charSequence, message) -> {
                // 反序列化数据
                MessageRequest messageRequest = MessageRequest.build(message);
                Long receiverUserId = messageRequest.getReceiverUserId();
                // 如果接收用户在本服务器上则进行转发
                Object object = RedisHashUtils.hashGet(NettyConstant.USER_CHANNEL_CACHE, receiverUserId.toString());
                if (StringUtils.isNotEmpty(object)){
                    // 1、获取当前用户所的channel
                    String clientChannelId = (String) object;
                    // 2、通过channelId获取本服务器与其的连接channel
                    Channel channel = NettyUtils.nettyChannelMap.get(clientChannelId);
                    if (StringUtils.isNotEmpty(channel)){
                        // 3、消息转发
                        channel.writeAndFlush(new TextWebSocketFrame(messageRequest.getMessage()));
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

